home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Univers Interactif 3
/
INTERACTIF.BIN
/
mac
/
Planete.net
/
Internet Confirmés_Vrac
/
NetAgent.sea
/
src
/
server.c
< prev
next >
Wrap
Text File
|
1992-06-15
|
15KB
|
562 lines
/*
This is an unsupported product. It was developed as part of a study at Ostfold
Regional College, Norway in the spring of 1992.
You use this software at your own risk. Neither the authors nor the Ostfold
Regional College nor any other person or organization except yourself is
responsible for any damage or loss of data derived from the use of this
software. You may distribute this software freely as long as it is in its
original form and all of its files are included. If you make any changes to any
part of this software or the files distributed with it, please state so and do
NOT distribute it under its original name.
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include "nntp_tcp.h"
#include "div_func.h"
#define MAXLEN 4
#define NO_OF_WORDS 4
#define NO_OF_KOMS 7
#define QUIT 0 /* Quits */
#define HELP 1 /* Sends help */
#define USER 2 /* Adds/verifies user */
#define RETV 3 /* Sends articles */
#define NWRD 4 /* Add a subject */
#define NWDS 5 /* Sets all subjects */
#define NNWS 6 /* Tells if new news has arrived */
typedef struct kommando {
char ord[NO_OF_WORDS][BUFSIZ+1];
int type;
}KOMMANDO;
char koms[NO_OF_KOMS][MAXLEN+1] = {
"quit",
"help",
"user",
"retv",
"nwrd",
"nwds",
"nnws"
};
int user_ok = 0;
char usernavn[BUFSIZ+1];
/*
-----------------------------------------------------------------------------
Function name: parse_msg()
-----------------------------------------------------------------------------
Parameters: char *s The string to parse.
Return value: Returns a struct of type KOMMANDO. If the command is not
recognized the structs type is set to -1.
Called by: do_server()
Calls: none
Description: Checks if the string s is a server command or not. If it is,
then it return it in a KOMMANDO struct.
-----------------------------------------------------------------------------
*/
KOMMANDO parse_msg(s)
char *s;
{
int x = 0, y = 0, t;
KOMMANDO k;
k.type = -1;
while( *s != '\0' && x < NO_OF_WORDS ) {
if( *s != 32 )
k.ord[x][y++] = *s;
else {
k.ord[x][y] = '\0';
y = 0;
x++;
}
s++;
}
k.ord[x][y] = '\0';
y = 0;
x++;
while( x < NO_OF_WORDS )
k.ord[x++][0] = '\0';
for( t = 0; t < NO_OF_KOMS; t++) {
if( stricmp(&k.ord[0][0], &koms[t][0]) == 0 )
k.type = t;
}
return(k);
}
/*
-----------------------------------------------------------------------------
Function name: fjern_forste()
-----------------------------------------------------------------------------
Parameters: char **s Pointer to a pointer to a string.
Return value: none
Called by: none
Calls: none
Description: Removes the first character in a string.
-----------------------------------------------------------------------------
*/
void fjern_forste(s)
char **s;
{
*s++;
}
/*
-----------------------------------------------------------------------------
Function name: reg_user()
-----------------------------------------------------------------------------
Parameters: int s A valid socket
KOMMANDO k A KOMMANDO struct
Return value: none
Called by: do_server()
Calls: tcp_send(), lock_file(), unlock_file(), les_linje()
Description: This function registrates a user or checks wether the user
exists or not. It uses the KOMMANDO struct to see if the user
exists, if not it initializes all of the files and makes a
directory for that user. It also updates the agent.users file
if it needs to. If the syntax of the command is wrong it
sends out an error message.
-----------------------------------------------------------------------------
*/
void reg_user(s, k)
int s;
KOMMANDO k;
{
int f;
char buf[BUFSIZ+1];
char user[BUFSIZ+1];
char buf2[BUFSIZ+1];
char innleggsfil[BUFSIZ+1];
if( (k.ord[1][0] == '\0') || (k.ord[2][0] == '\0')) {
tcp_send(s, "451 usage: user name passwd\n");
return;
}
if((f = open("agent.users", O_CREAT|O_RDWR, S_IREAD|S_IWRITE)) == -1) {
tcp_send(s, "503 server error\n");
return;
}
lock_file(f);
sprintf(user, "%s %s", &k.ord[1][0], &k.ord[2][0]);
while(les_linje( f, buf)) {
if(stricmp(user, buf) == 0) {
strcpy(usernavn, &k.ord[1][0]);
user_ok = 1;
tcp_send(s, "250 user ok\n");
unlock_file(f);
close(f);
return;
}
else {
first_word(buf);
if(stricmp(buf,&k.ord[1][0]) == 0) {
tcp_send(s, "444455 user login incorrect\n");
unlock_file(f);
close(f);
return;
}
}
}
sprintf(user, "%s\n", user);
if(write(f, user, strlen(user)) == -1) {
tcp_send(s, "503 server error\n");
return;
}
unlock_file(f);
close(f);
if(mkdir(&k.ord[1][0], 511) != 0 ) {
tcp_send(s, "503 server error\n");
perror("mkdir");
return;
}
sprintf(innleggsfil, "%s/%s.subjects", &k.ord[1][0], &k.ord[1][0]);
if((f = open(innleggsfil, O_CREAT|O_RDWR, S_IREAD|S_IWRITE)) == -1) {
tcp_send(s, "503 server error\n");
return;
}
lock_file(f);
unlock_file(f);
close(f);
strcpy(usernavn, &k.ord[1][0]);
user_ok = 1;
tcp_send(s, "252 new user ok\n");
}
/*
-----------------------------------------------------------------------------
Function name: help()
-----------------------------------------------------------------------------
Parameters: int s A valid socket.
Return value: none
Called by: do_server()
Calls: tcp_send()
Description: Gives a respond to the HELP command. It sends all the data
to s.
-----------------------------------------------------------------------------
*/
void help(s)
int s;
{
tcp_send(s, "202 help requested, help follows\n");
tcp_send(s, "NetAgent deamon version 0.9\n");
tcp_send(s, "Written by the NetAgent Project at Ostfold Regional College 1992\n");
tcp_send(s, " (Per H. Johansen, Nina B. Olsen, Morten Kristiansen)\n");
tcp_send(s, "----------------------------------------------------------------\n");
tcp_send(s, "The server supports the following commands:\n");
tcp_send(s, " USER RETV QUIT NWRD\n");
tcp_send(s, " HELP NWDS NNWS\n");
tcp_send(s, ".\n");
}
/*
-----------------------------------------------------------------------------
Function name: send_command_error()
-----------------------------------------------------------------------------
Parameters: int s A valid socket
Return value: none
Called by: none
Calls: tcp_send()
Description: Sends an error message to s if a command is not implemented.
-----------------------------------------------------------------------------
*/
void send_command_error(s)
int s;
{
tcp_send(s,"501 command not implemented\n");
}
/*
-----------------------------------------------------------------------------
Function name: send_user_error()
-----------------------------------------------------------------------------
Parameters: int s A valid socket
Return value: none
Called by: do_server()
Calls: tcp_send()
Description: Sends out an error message if someone gives it a command
which is user dependent and no user is logged in.
-----------------------------------------------------------------------------
*/
void send_user_error(s)
int s;
{
tcp_send(s,"452 no user logged in\n");
}
/*
-----------------------------------------------------------------------------
Function name: nytt_ord()
-----------------------------------------------------------------------------
Parameters: int s A valid socket.
char *t pointer to a string.
Return value: none
Called by: do_server()
Calls: tcp_send(), lock_file(), unlock_file()
Description: This function add a new subject to the users <user>.subjects
file. The subject to be added is pointed to by t.
-----------------------------------------------------------------------------
*/
void nytt_ord(s, t)
int s;
char *t;
{
char fil[BUFSIZ+1];
char stikkord[BUFSIZ+1];
int f;
if( *t == '\0') {
tcp_send(s, "454 usage: nwrd word\n");
return;
}
sprintf(fil, "%s/%s.subjects", usernavn, usernavn);
if((f = open(fil, O_CREAT|O_RDWR|O_APPEND, S_IREAD|S_IWRITE)) == -1) {
tcp_send(s, "503 server error\n");
return;
}
lock_file(f);
sprintf(stikkord, "%s\n", t);
if(write(f, stikkord, strlen(stikkord)) == -1) {
tcp_send(s, "503 server error\n");
return;
}
unlock_file(f);
close(f);
tcp_send(s, "254 word added to list\n");
}
/*
-----------------------------------------------------------------------------
Function name: nytt()
-----------------------------------------------------------------------------
Parameters: int s A valid socket.
Return value: none
Called by: do_server()
Calls: tcp_send(), lock_file(), unlock_file(), les_linje
Description: This function send the contents of the file <user>.articles
to the socket s. The transmission is ended with a '.'.
-----------------------------------------------------------------------------
*/
void nytt(s)
int s;
{
char buf[BUFSIZ+1];
char command[BUFSIZ+1];
char fil[BUFSIZ+1];
int f;
sprintf(fil, "%s/%s.articles", usernavn, usernavn);
if((f = open(fil, O_CREAT|O_RDONLY|O_APPEND, S_IREAD|S_IWRITE)) == -1) {
tcp_send(s, "503 server error\n");
return;
}
lock_file(f);
tcp_send(s, "230 new news follows\n");
while(les_linje(f, buf)) {
sprintf(command, "%s\n", buf);
tcp_send(s, command);
}
tcp_send(s, ".\n");
unlock_file(f);
close(f);
if((f = open(fil, O_CREAT|O_WRONLY|O_TRUNC)) == -1) {
tcp_send(s, "503 server error\n");
return;
}
lock_file(f);
unlock_file(f);
close(f);
sprintf(fil, "%s/%s.newnews", usernavn, usernavn);
if((f=open(fil, O_CREAT|O_RDWR|O_TRUNC, S_IREAD|S_IWRITE)) == -1 ){
tcp_send(s, "503 server error\n");
return;
}
lock_file(f);
write(f, "NO\n", 3);
unlock_file(f);
close(f);
}
/*
-----------------------------------------------------------------------------
Function name: new_words()
-----------------------------------------------------------------------------
Parameters: int s A valid socket
Return value: none
Called by: do_server()
Calls: tcp_send(), lock_file(), unlock_file(), get_list()
Description: This function recives a list of new subjects. The list must
end with a '.'. The list is written to the <user>.subjects
file.
-----------------------------------------------------------------------------
*/
void new_words(s)
int s;
{
int f;
char filnavn[BUFSIZ+1];
tcp_send(s, "256 send new keywords\n");
sprintf(filnavn, "%s/%s.subjects", usernavn, usernavn);
if((f = open(filnavn, O_CREAT|O_WRONLY|O_TRUNC, S_IREAD|S_IWRITE)) == -1) {
tcp_send(s, "503 server error\n");
return;
}
lock_file(f);
get_list(s, f, 3600);
unlock_file(f);
close(f);
}
/*
-----------------------------------------------------------------------------
Function name: new_news()
-----------------------------------------------------------------------------
Parameters: int s A valid socket
Return value: none
Called by: do_server()
Calls: tcp_send(), lock_file(), unlock_file(), les_linje()
Description: This function sends a response which says if the user has new
news waiting. It reads the status from the <user>.newnews
file.
-----------------------------------------------------------------------------
*/
void new_news(s)
int s;
{
char buf[BUFSIZ+1];
char fil[BUFSIZ+1];
int f;
sprintf(fil, "%s/%s.newnews", usernavn, usernavn);
if((f=open(fil, O_CREAT|O_RDONLY, S_IREAD|S_IWRITE)) == -1 ){
tcp_send(s, "503 server error\n");
return;
}
lock_file(f);
if (les_linje(f, buf) <= 0) {
tcp_send(s, "456 no new news\n");
return;
}
if( stricmp(buf, "YES") == 0)
tcp_send(s, "270 new news\n");
else
tcp_send(s, "456 no new news\n");
unlock_file(f);
close(f);
if((f=open(fil, O_CREAT|O_RDWR|O_TRUNC, S_IREAD|S_IWRITE)) == -1 ){
tcp_send(s, "503 server error\n");
return;
}
lock_file(f);
write(f, "NO\n", 3);
unlock_file(f);
close(f);
}
/*
-----------------------------------------------------------------------------
Function name: do_server()
-----------------------------------------------------------------------------
Parameters: int s A valid socket
Return value: none
Called by: main() (agentd)
Calls: tcp_send(), recv_upto(), help(), reg_user(),
send_user_error(), nytt(), nytt_ord(), new_words(),
new_news(), parse_msg()
Description: This is the core function of the server. It handles all
incomming commands and distributes them to the correct
functions.
-----------------------------------------------------------------------------
*/
void do_server(s)
int s;
{
char command[BUFSIZ+1];
char localhost[33];
char *buf;
char melding[BUFSIZ+1];
int slutt = 0;
KOMMANDO k;
gethostname(localhost, 32);
sprintf(command, "200 NetAgent deamon(%s) version 0.9 ready.\n", localhost);
tcp_send(s, command);
melding[0] = '\0';
k.type = -2;
while(!slutt) {
if(recv_upto(s, RETURN, melding, 3600) <= 0) {
tcp_send(s, "505 error or timeout - closing\n");
close(s);
exit(1);
}
buf = melding;
if(*buf == LINEFEED)
buf++;
k = parse_msg(buf);
switch(k.type) {
case QUIT:
tcp_send(s, "205 closing connection - goodbye\r\n");
slutt = 1;
break;
case HELP:
help(s);
break;
case USER:
reg_user(s, k);
break;
case RETV:
if(user_ok)
nytt(s);
else
send_user_error(s);
break;
case NWRD:
if(user_ok)
nytt_ord(s, &k.ord[1][0]);
else
send_user_error(s);
break;
case NWDS:
if(user_ok)
new_words(s);
else
send_user_error(s);
break;
case NNWS:
if(user_ok)
new_news(s);
else
send_user_error(s);
break;
default:
tcp_send(s, "500 command not recognized\r\n");
break;
}
}
close(s);
exit(0);
}